package edu.washington.cs.workflow.spec4j.example;

import java.util.Collection;

import org.uispec4j.ListBox;
import org.uispec4j.Panel;
import org.uispec4j.Table;
import org.uispec4j.Trigger;
import org.uispec4j.UIComponent;
import org.uispec4j.UISpec4J;
import org.uispec4j.UISpecTestCase;
import org.uispec4j.Window;
import org.uispec4j.finder.ComponentMatcher;
import org.uispec4j.interception.MainClassAdapter;
import org.uispec4j.interception.WindowHandler;
import org.uispec4j.interception.WindowInterceptor;

import edu.washington.cs.workflow.analysis.guistructure.ExceptionalExecution;
import edu.washington.cs.workflow.analysis.guistructure.Spec4JUtils;
import edu.washington.cs.workflow.analysis.guistructure.UIActionTracer;
import edu.washington.cs.workflow.analysis.guistructure.uievents.MenuItemEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent.WINDOW;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEventOutcome;
import edu.washington.cs.workflow.util.Utils;

/**
 * Add the whole experiments/gantt2.5.4 to the classpath,
 * also the file: eclipsito.jar
 * 
 * be aware of the jar order, put eclipsito.jar above spec4j
 * 
 * */

//find the trace in C:/Users/szhang/ganttproject.log
public class TestGanttProgram extends UISpecTestCase {
	
	static {
        UISpec4J.init();
    } 
	
	protected void setUp() throws Exception {
//		org.bardsoftware.eclipsito.Boot
//		ganttproject-eclipsito-config.xml
		Class<?> clz = Class.forName("org.bardsoftware.eclipsito.Boot");
	    setAdapter(new MainClassAdapter(clz, new String[]{"ganttproject-eclipsito-config.xml"}));
	}
	
	public void testShowAllActions() {
		UISpec4J.setWindowInterceptionTimeLimit(50000);
		System.out.println("getting window");
		Window window = getMainWindow();
		System.out.println("window: " + window);
		System.out.println(window.getDescription());
		
       Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		
		for(UIEvent event : events) {
			System.out.println(event + ",  can fire: " + event.canFireEvent());
		}
	}
	
	//button: Zoom In
	public void testZoomIn() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		for(UIEvent event : events) {
			System.out.println(event);
			if(event.toString().indexOf("Zoom In") != -1) {
				if(event.canFireEvent()) {
					System.err.println(event);
					event.probeWindowInfo();
				} else {
					System.err.println("=================");
				}
			}
		}
	}
	
	//button: Next,
	public void testButtonNext() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		for(UIEvent event : events) {
			System.out.println(event);
			if(event.toString().indexOf("button: Next,") != -1) {
				if(event.canFireEvent()) {
					System.err.println(event);
					event.probeWindowInfo();
				} else {
					System.err.println("=================");
				}
			}
		}
	}
	
	//: Show critical path,
	//button: Next,
	public void testShowCriticalpath() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		for(UIEvent event : events) {
			System.out.println(event);
			if(event.toString().indexOf(": Show critical path,") != -1) {
				if(event.canFireEvent()) {
					System.err.println(event);
					event.probeWindowInfo();
				} else {
					System.err.println("=================");
				}
			}
		}
	}
	
	// Edit, Settings
	@Deprecated
	//the chart option has been deleted
	public void testEditSettings() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		for(UIEvent event : events) {
			System.out.println(event);
			if(event.toString().indexOf("Edit, Settings") != -1) {
				if(event.canFireEvent()) {
					System.err.println(event);
					event.probeWindowInfo();
					
				} else {
					System.out.println("=================");
				}
			}
		}
	}
	
	@Deprecated
	public void testNewResourceAndDelete() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		for(UIEvent event : events) {
//			System.out.println(event);
			if(event.toString().indexOf("null, New Resource") != -1) {
				if(event.canFireEvent()) {
					WINDOW w = event.probeWindowInfo();
					System.out.println(" -- " + event);
					UIEventOutcome outcome = event.fireEvent();
					Trigger t = outcome.getTrigger();
					WindowInterceptor.init(t).process(new WindowHandler() {
					    public Trigger process(Window dialog) {
					      return dialog.getButton("OK").triggerClick();
					    }
					  }).run();
					
				} else {
					System.err.println("=================");
				}
			}
		}
		
		for(UIEvent event : events) {
			if(event.canFireEvent()) {
				if(event.toString().indexOf("Resources Chart") != -1) {
					WINDOW w = event.probeWindowInfo();
					event.fireEvent();
					System.out.println(" -- " + event);
					System.out.println(" -- Windows : " + w);
				}
			}
		}
		
		for(UIEvent event : events) {
			if(event.canFireEvent()) {
				if(event.toString().indexOf("Click button:") != -1) {
					WINDOW w = event.probeWindowInfo();
					System.out.println(" xxx " + event + " -- Windows : " + w);
				}
			}
		}
	}
	
	public void testGetWindow() {
		System.out.println("getting window");
		Window window = getMainWindow();
		System.out.println("window: " + window);
		System.out.println(window.getDescription());
		
       Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		
		for(UIEvent event : events) {
			System.out.println(event);
			if(event.canFireEvent()) {
				if(event instanceof MenuItemEvent) {
					if(((MenuItemEvent)event).getMenuLabel().toLowerCase().trim().equals("quit")) {
						Utils.debugPrintln("Skip the quit menu");
						continue;
					}
				}
			    event.probeWindowInfo();
			    event.fireEvent();
			}
		}
		
	}
	
	//save the previous state, baselines -> add -> OK
	//Baselines...,
	public void testSavePreviousState() {
			Window window = getMainWindow();
			Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
			
			for(UIEvent event : events) {
				if(event.canFireEvent()) {
					if(event.toString().indexOf("New task,") != -1) {
						WINDOW w = event.probeWindowInfo();
						event.fireEvent();
					}
				}
			}
			
			for(UIEvent event : events) {
				System.out.println(event);
				if(event.toString().indexOf("Baselines...") != -1) {
					if(event.canFireEvent()) {
						System.err.println(event);
						event.probeWindowInfo();
						
						UIEventOutcome outcome = event.fireEvent();
						
						Utils.checkTrue(outcome.isModalWindow());
						
						Trigger t = outcome.getTrigger();
						WindowInterceptor.init(t).process(new WindowHandler() {
						    public Trigger process(Window dialog) {
						    	
						     Collection<UIEvent> events = Spec4JUtils.allAvailableUIEvents(dialog);
						     for(UIEvent e : events) {
						    	 System.out.println("Event: " + e);
						    	 e.probeWindowInfo();
						    	 e.fireEvent();
						     }
						    	
//						      UIActionTracer.tracer.traceAction("Click Add");
//						      dialog.getButton("Add").triggerClick();
						      
//						      UIComponent[] uis = dialog.getUIComponents(ComponentMatcher.ALL);
//						      for(UIComponent ui : uis) {
//						    	  if(ui instanceof Table) {
//						    		  Table t = (Table)ui;
//						    	      System.out.println("   --> " + ui + ",  " + (ui == null ? "null " : ui.getDescription())
//						    	    		  + t.getColumnCount() + ", " + t.getRowCount());
//						    	      UIActionTracer.tracer.traceAction("Edit table input name");
//						    	      t.editCell(0, 0, "hello", true);
//						    	  }
//						      }
						      
//						      Collection<UIEvent> events  = Spec4JUtils.allNonNullUIEvent(dialog);
//						      for(UIEvent event : events) {
//						    	  System.out.println("~~~ " + event);
//						      }
						      
						      
//						      UIActionTracer.tracer.traceAction("Click OK");
						      return dialog.getButton("OK").triggerClick();
						      
//						      return Trigger.DO_NOTHING;
						    }
						  }).run();
						
					} else {
						System.err.println("=================");
					}
				}
			}
	}
	

	//boot class:
	//org.bardsoftware.eclipsito.Boot
//	public static void main(String[] args) throws ClassNotFoundException {
//		org.bardsoftware.eclipsito.Boot.main(new String[]{"ganttproject-eclipsito-config.xml"});
//	}
	
//	// Edit, Settings
//	public void testChartOption20() {
//		Window window = getMainWindow();
//		Collection<UIEvent> events = Spec4JUtils.allNonNullUIEvent(window);
//		for(UIEvent event : events) {
//			System.out.println(event);
//			if(event.toString().indexOf("View, Chart options") != -1) {
//				if(event.canFireEvent()) {
//					System.err.println(event);
//					event.probeWindowInfo();
//				} else {
//					System.err.println("=================");
//				}
//			}
//		}
//	}
	
}